package aftersale

import (
	"context"
	"fmt"
	"strconv"
	"strings"

	"mall/common/globalkey"
	"mall/common/jwt"
	"mall/common/resultx"
	"mall/common/uniqueidx"
	"mall/common/utils/pointy"
	"mall/service/attachment/rpc/attachmentclient"
	"mall/service/forum/api/internal/svc"
	"mall/service/forum/api/internal/types"
	"mall/service/forum/rpc/forumclient"
	"mall/service/order/rpc/orderclient"

	"github.com/zeromicro/go-zero/core/logx"
)

type CreateAfterSaleLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

// 添加售后申请
func NewCreateAfterSaleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateAfterSaleLogic {
	return &CreateAfterSaleLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *CreateAfterSaleLogic) CreateAfterSale(req *types.AfterSaleInfo, headers *[]*types.Header) (resp *types.CreateAfterSaleRes, err error) {
	if req.Mobile == nil || len(strings.TrimSpace(*req.Mobile)) == 0 {
		return nil, resultx.NewErrCode(resultx.AFTER_SALE_PARAM_INVALID)
	}
	if req.AfterSaleType == nil || *req.AfterSaleType == 0 {
		return nil, resultx.NewErrCode(resultx.AFTER_SALE_PARAM_INVALID)
	}
	if req.OrderItemId == nil || *req.OrderItemId < 0 {
		return nil, resultx.NewErrCode(resultx.AFTER_SALE_PARAM_INVALID)
	}
	userId := jwt.GetUserId(l.ctx)
	if userId == 0 {
		return nil, resultx.NewErrCode(resultx.TOKEN_EXPIRE_ERROR)
	}
	//处理图片
	newThumbMap := make(map[string]*types.MediaInfo)
	var Media []*forumclient.ForumMediaInfo
	var MediaIds []string
	var newAttachmentIds []string
	if len(req.Media) > 0 {
		for idx, v := range req.Media {
			if v.Order == nil {
				v.Order = pointy.GetPointer(uint32(idx))
			}
			if v.Id != nil && len(*v.Id) > 0 {
				if _, ok := newThumbMap[*v.Id]; !ok { // 忽略重复id
					newThumbMap[*v.Id] = v
					MediaIds = append(MediaIds, *v.Id)
				}
			} else {
				var thumbnail *uint32
				if v.Thumbnail != nil && *v.Thumbnail {
					thumbnail = pointy.GetPointer(uint32(1))
				}
				Media = append(Media, &forumclient.ForumMediaInfo{ // 第三方图片
					Uid:       v.Uid,
					Url:       v.Url,
					Thumbnail: thumbnail,
					AltText:   v.AltText,
					Meta:      v.Details,
					Order:     v.Order,
				})
			}
		}
	}
	// 根据 MediaIds 查询 attachments 记录到 forum_attachment_relationships
	if len(MediaIds) > 0 {
		res, err := l.svcCtx.AttachmentRpc.BackendGetFileList(l.ctx, &attachmentclient.FileListReq{
			Ids: pointy.GetPointer(strings.Join(MediaIds, ",")),
		})
		if err != nil {
			return nil, err
		}
		if len(res.List) > 0 {
			for _, v := range res.List {
				var url *string
				if v.Url != nil && len(*v.Url) > 0 {
					url = pointy.GetPointer(fmt.Sprintf("%s%s", l.svcCtx.Config.NfsConf.StaticUrl, *v.Url))
				}
				if url == nil && v.Path != nil && len(*v.Path) > 0 {
					url = pointy.GetPointer(fmt.Sprintf("%s%s", l.svcCtx.Config.NfsConf.ProxyUrl, *v.Path))
				}
				if media, ok := newThumbMap[*v.Id]; ok {
					var thumbnail *uint32
					if media.Thumbnail != nil && *media.Thumbnail {
						thumbnail = pointy.GetPointer(uint32(1))
					}
					Media = append(Media, &forumclient.ForumMediaInfo{
						Uid:       media.Uid,
						Id:        v.Id,
						Uri:       media.Url,
						Url:       url,
						Thumbnail: thumbnail,
						AltText:   media.AltText,
						Meta:      media.Details,
						Order:     media.Order,
					})
					newAttachmentIds = append(newAttachmentIds, *v.Id)
				}
			}
		}
	}
	var media []*orderclient.MediaInfo
	for _, v := range newThumbMap {
		var t uint32

		if v.Thumbnail != nil || *v.Thumbnail {
			t = 1
		}
		media = append(media, &orderclient.MediaInfo{
			Uid:       v.Uid,
			Id:        v.Id,
			Thumbnail: pointy.GetPointer(t),
			Order:     v.Order,
			Url:       v.Url,
			MimeType:  pointy.GetPointer(strconv.Itoa(int(globalkey.AttachmentLogForumAfterSale))),
			AltText:   v.AltText,
			MetaData:  v.MetaData,
		})
	}
	//生成sn  确定售后状态
	var afterSaleSn string
	var afterSaleType uint32
	if *req.AfterSaleType == globalkey.AfterSaleTypeRefund { // 退款
		afterSaleType = globalkey.AfterSaleTypeRefund
		afterSaleSn = uniqueidx.GenSn(uniqueidx.SN_PREFIX_Refund)
		*req.Status = globalkey.OrderTradeStateRefundApply
	} else if *req.AfterSaleType == globalkey.AfterSaleTypeReturn { // 退货
		afterSaleType = globalkey.AfterSaleTypeReturn
		afterSaleSn = uniqueidx.GenSn(uniqueidx.SN_PREFIX_Return)
		*req.Status = globalkey.OrderTradeStateReturnApply
	} else if *req.AfterSaleType == globalkey.AfterSaleTypeBarter { // 换货
		afterSaleType = globalkey.AfterSaleTypeBarter
		afterSaleSn = uniqueidx.GenSn(uniqueidx.SN_PREFIX_Barter)
		*req.Status = globalkey.OrderTradeStateReturnApply
	}

	//确定退款类型
	if req.ReturnType != nil || *req.RefundType > 0 {
		if uint32(*req.RefundType) == globalkey.SourceRefund {
			*req.RefundType = globalkey.SourceRefund
		} else {
			*req.RefundType = globalkey.OtherRefund
		}
	}
	//确定退货类型
	if req.ReturnType != nil || *req.ReturnType > 0 {
		if uint32(*req.ReturnType) == globalkey.ExpressDeliveryReturn {
			*req.ReturnType = globalkey.ExpressDeliveryReturn
		} else {
			*req.ReturnType = globalkey.OtherReturn
		}
	}
	res, err := l.svcCtx.OrderRpc.CreateAfterSale(l.ctx, &orderclient.AfterSaleInfo{
		AfterSaleSn:    pointy.GetPointer(afterSaleSn),
		OrderId:        req.OrderId,
		OrderItemId:    req.OrderItemId,
		OrderSn:        req.OrderSn,
		ProductId:      req.ProductId,
		ProductCode:    req.ProductCode,
		ProductSkuId:   req.ProductSkuId,
		ProductSkuCode: req.ProductSkuCode,
		ProductSku:     req.ProductSku,
		SkuThumbUrl:    req.SkuThumbUrl,
		ProductTitle:   req.ProductTitle,
		ProductPrice:   req.ProductPrice,
		Quantity:       req.Quantity,

		UserId:          pointy.GetPointer(userId),
		NickName:        req.NickName,
		Mobile:          req.Mobile,
		ReturnAddressId: req.ReturnAddressId,
		AfterSaleType:   pointy.GetPointer(afterSaleType),
		RefundType:      req.RefundType,
		ReturnType:      req.ReturnType,
		RefundAmount:    req.RefundAmount,
		RefundDetails:   req.RefundDetails,
		Remark:          req.Remark,
		Status:          req.Status,
		Media:           media,
	})
	if err != nil {
		return nil, err
	}

	if len(newAttachmentIds) > 0 {
		_, err = l.svcCtx.AttachmentRpc.CreateFileLog(l.ctx, &attachmentclient.CreateFileLogReq{
			FileIds:    newAttachmentIds,
			Put:        pointy.GetPointer(uint32(1)),
			ObjectId:   pointy.GetPointer(res.Id),
			ObjectType: pointy.GetPointer(uint32(globalkey.AttachmentLogTypeAfterSale)),
		})
		if err != nil {
			logx.Errorw("CreateAfterSale CreateFileLog err", logx.Field("detail", err.Error()))
		}
	}

	return &types.CreateAfterSaleRes{
		Id: res.Id,
	}, nil
}
